
/*
Generator:异步编程的比较高级的方法
1.next()函数的用法
2.yield*的语法
*/

{
  //Generator基本定义
  let tell = function* (){
    yield 'a';
    yield 'b';
    return 'c'
  }
  let k=tell();
  console.log(k.next());
  console.log(k.next());
  console.log(k.next());
  console.log(k.next());
}

{
  let obj={};
  obj[Symbol.iterator]=function* (){
    yield 1;
    yield 2;
    yield 3;
  }
  for(let val of obj){
    console.log(val);
  }
}

{
  //状态机  无限循环的状态机
  let state=function* (){
    while (1) {
      yield 'A';
      yield 'B';
      yield 'C';
    }
  }
  let status=state();
  console.log(status.next());//A
  console.log(status.next());//B
  console.log(status.next());//C
  console.log(status.next());//A
  console.log(status.next());//B
  console.log(status.next());//C
}

// {
//   //语法糖
//   let state=asnyc function (){
//     while (1) {
//       await 'A';
//       await 'B';
//       await 'C';
//     }
//   }
//   let status=state();
//   console.log(status.next());//A
//   console.log(status.next());//B
//   console.log(status.next());//C
//   console.log(status.next());//A
//   console.log(status.next());//B
//   console.log(status.next());//C
//
// }

{
  //在什么场景上面引用Generator函数
  //抽奖环节，当前账户下面用户能够抽奖依次减少
  let drew=function(count){
    //具体抽奖逻辑
    console.info(`剩余${count}次`);
  }
  let residue=function* (count){
    while (count>0) {
      count--;
      yield drew(count);
    }
  }
  let start=residue(5);
  let btn=document.createElement('button');
  btn.id='start';
  btn.textContent='抽奖';
  document.body.appendChild(btn);
  document.getElementById('start').addEventListener('click',function(){
    start.next();
  },false)
}

{
  //服务器的某一个状态定期的去变化，需要定时去服务端取得状态
  //长轮询
  let ajax=function* (){
    yield new Promise(function(resolve,reject){
      setTimeout(function() {
        resolve({code:0})
      },2000)
    })
  }
  let pull=function(){
    let genertor=ajax();
    let step=genertor.next();
    step.value.then(function(d){
      if(d.code!=0){
        setTimeout(function(){
          console.log('wait');
          pull();
        },1000)
      }else {
        console.info(d)
      }
    })
  }
  pull()
}

{
  let flat=function* (a) {
      var len=a.length;
      for (var i = 0; i < len; i++) {
            if (Array.isArray(a[i]))
            yield* flat(a[i])
            else yield a[i]
          }
  }
  let arr=[1,[2,[3,[4,5],6],7],8];
  for(let val of flat(arr)){
    console.log(val);
  }
}
